package com.ruoyi.system.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.RedisConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.redis.RedisClientUtil;
import com.ruoyi.common.utils.Base64Util;
import com.ruoyi.common.utils.OkHttpUtils;
import com.ruoyi.common.utils.security.Md5Utils;
import com.ruoyi.system.api.ResponseWithData;
import com.ruoyi.system.api.domain.*;
import com.ruoyi.system.api.mapper.LoginLogMapper;
import com.ruoyi.system.api.mapper.UserMapper;
import com.ruoyi.system.api.service.IConfigurationService;
import com.ruoyi.system.api.service.IInterfaceOperationLogService;
import com.ruoyi.system.api.service.IUserService;
import com.ruoyi.system.api.service.LoginService;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;
import okhttp3.FormBody;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import redis.clients.jedis.Jedis;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @ClassName LoginServiceImpl
 * @Description: TODO
 * @Author shihx
 * @Date 2020/2/24
 * @Version V1.0
 **/
@Service
public class LoginServiceImpl implements LoginService {

    private static final Logger log = LoggerFactory.getLogger(LoginServiceImpl.class);

    /**
     * 配置文件
     */
    @Autowired
    private Global global;

    /**
     * redis配置文件
     */
    @Autowired
    private RedisConfig redisConfig;

    /**
     * 用户表
     */
    @Autowired
    private IUserService iUserService;

    /**
     * 接口调用日志
     */
    @Autowired
    private IInterfaceOperationLogService iInterfaceOperationLogService;

    /**
     * 系统配置项
     */
    @Autowired
    private IConfigurationService configurationService;

    @Autowired
    private LoginLogMapper loginLogMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ISysUserService sysUserService;



    @Override
    public ResponseWithData<?> login(Login login, SysUser sysUser) throws Exception {

        log.info("登陆用户信息：" + JSONObject.toJSONString(login));

        String ccServerUrl = global.getCcServerUrl();
//        StringBuffer url = new StringBuffer("http://www.thermo.com.cn/ServiceApp/Auth.asmx/CheckEngInfo?output=json");
        StringBuffer url = new StringBuffer();
        url.append(ccServerUrl);
        url.append("Auth.asmx/CheckEngInfo");

        /** POST请求 参数赋值 */
        FormBody.Builder builder = new FormBody.Builder();
        builder.add("Email", login.getEmail());
        builder.add("PassWord", login.getPassword());


        /** 先保存接口参数 */
        InterfaceOperationLog interfaceOperationLog = new InterfaceOperationLog();
        interfaceOperationLog.setInterfaceName("登录接口");
        interfaceOperationLog.setInterfaceType("login");
        interfaceOperationLog.setInterfaceUrl(url.toString());
        //涉及用户密码不保存
        //interfaceOperationLog.setInterfaceRequest(JSONObject.toJSONString(login));
        interfaceOperationLog.setStartTime(new Date());
        iInterfaceOperationLogService.insertInterfaceOperationLog(interfaceOperationLog);

        /** 保存登陆日志 */
        LoginLog loginLog = new LoginLog();
        loginLog.setEmail(login.getEmail());
        //涉及用户密码不保存
//        loginLog.setPassword(login.getPassword());
        loginLog.setSiolId(interfaceOperationLog.getId());
        loginLog.setRegistrationId(login.getRegistrationId());
        loginLog.setPhoneUuid(login.getPhoneUuid());
        loginLog.setVersionName(login.getVersionName());
        loginLog.setVersionCode(login.getVersionCode());
        loginLog.setModel(login.getModel());
        loginLog.setOsversion(login.getOsversion());
        loginLog.setCreateTime(new Date());
        loginLogMapper.insertLoginLog(loginLog);

        Response res = null;
        String interfaceResponse = "";
        String interfaceResponseBody = "";
        String interfaceState = "";
        try {
            /** 调用CC端接口 */
            res = OkHttpUtils.getInstance().postRequest(url.toString(), builder.build());
            interfaceResponse = res.toString();
            interfaceResponseBody = res.body().string();
            //涉及用户密码不保存
            //interfaceResponse += " Body参数：" + interfaceResponseBody;
            log.info("调用CC端返回结果：" + interfaceResponseBody);
            if (res.code() == 200) {
                interfaceState = "1";
            } else {
                interfaceState = "2";
            }
        } catch (Exception e) {
            log.info("调用CC端返回结果：" + interfaceResponseBody);
            interfaceResponse = e.getMessage();
            interfaceState = "0";
        }

        /** 更新接口返回结果 */
        interfaceOperationLog.setEndTime(new Date());
        interfaceOperationLog.setInterfaceResponse(interfaceResponse);
        interfaceOperationLog.setInterfaceState(interfaceState);
        iInterfaceOperationLogService.updateInterfaceOperationLog(interfaceOperationLog);

        /** 如果调用接口异常直接返回 */
        if ("0".equals(interfaceState)) {
            loginLog.setLoginState("2");
            loginLog.setUpdateTime(new Date());
            loginLogMapper.updateLoginLog(loginLog);
            return new ResponseWithData().success().msg("登录失败 调用CC端登录接口发生异常").code(202);
        }

        if (res.code() == 200) {
            JSONObject obj = JSON.parseObject(interfaceResponseBody);
            if ("1".equals(obj.getString("status"))) {

//                /** 获取CC端登陆接口用户信息 */
//                if (StringUtils.isEmpty(obj.getString("record")) || StringUtils.equals("该用户被停用！", obj.getString("message"))) {
//                    return new ResponseWithData().success().msg("该用户被停用！").code(204);
//                }

                JSONObject loginUser = obj.getJSONArray("record").getJSONObject(0);
                /** 验证当前登陆用户数据库中是否存在 */
                if (ObjectUtils.isEmpty(loginUser)) {
                    return logOut(login,obj);
                }
                User user = new User();

                user.setEnginnerId(loginUser.getLong("enginner_id"));
                List<User> list = iUserService.selectUserList(user);
                user.setEmail(login.getEmail());
                //涉及用户密码不保存
//                user.setPassword(login.getPassword());
                user.setPhoneUuid(login.getPhoneUuid());
                user.setRegistrationId(login.getRegistrationId());
                user.setName(loginUser.getString("NAME"));
                user.setCsrcode(loginUser.getString("Csrcode") == null ? "" : loginUser.getString("Csrcode"));
                user.setCsrname(loginUser.getString("Csrname") == null ? "" : loginUser.getString("Csrname"));
                user.setLevel(loginUser.getString("ACTIVE_FLAG") == null ? "" : loginUser.getString("ACTIVE_FLAG"));
                user.setMobile(loginUser.getString("MOBILE") == null ? "" : loginUser.getString("MOBILE"));
                user.setPosition(loginUser.getString("Position") == null ? "" : loginUser.getString("Position"));
                user.setSapcode(loginUser.getString("Sap_UserID") == null ? "" : loginUser.getString("Sap_UserID"));
                user.setWorkday(loginUser.getString("WorkDay") == null ? "" : loginUser.getString("WorkDay"));
                user.setTeamleaderId(loginUser.getString("tlid") == null ? "" : loginUser.getString("tlid"));
                user.setTeamleaderName(loginUser.getString("tlname") == null ? "" : loginUser.getString("tlname"));
                user.setDiv1(loginUser.getString("div") == null ? "" : loginUser.getString("div"));
                user.setBu(loginUser.getString("bu") == null ? "" : loginUser.getString("bu"));

                //更新维护信息
                interfaceOperationLog.setFseId(loginUser.getString("enginner_id"));
                interfaceOperationLog.setFseName(loginUser.getString("NAME"));
                iInterfaceOperationLogService.updateInterfaceOperationLog(interfaceOperationLog);

                /** 生成access_token 并存放至redis */
                RedisClientUtil.getInstance().initialPool(redisConfig.getIp(), redisConfig.getPort(), redisConfig.getPassword(), redisConfig.getTimeout());
                Jedis redis = RedisClientUtil.getInstance().getJedis();
                /** 如果这个key在redis中存在则删除 */

                if (StringUtils.isNotEmpty(redis.get(loginUser.getLong("enginner_id") + ""))) {
                    String token = redis.get(loginUser.getLong("enginner_id") + "");
                    redis.del(loginUser.getLong("enginner_id") + "");
                    redis.del(token);
                }
                /** 生成新的ACCESS_TOKEN   token-apikey*/
                String AccessToken = UUID.randomUUID().toString().replaceAll("-", "") + "-" + loginUser.getLong("enginner_id");
                AccessToken = Base64Util.encode(AccessToken);//加密

                /** 正存 */
                redis.set(loginUser.getLong("enginner_id") + "", AccessToken);
                redis.persist(loginUser.getLong("enginner_id") + "");
                /** 反存 */
                redis.set(AccessToken, loginUser.getLong("enginner_id") + "");
                redis.persist(AccessToken);
                log.info("AccessToken----------------"+AccessToken+"-----enginner_id---"+loginUser.getLong("enginner_id"));
                user.setToken(AccessToken);
                /** 如果存在更新 */
                if (list != null && list.size() > 0) {
                    user.setId(list.get(0).getId());
                    user.setUpdateTime(new Date());
                    iUserService.updateUser(user);
                }
                /** 否则新增 */
                else {
                    user.setCreateTime(new Date());
                    iUserService.insertUser(user);

                    // 手机端用户新增的同时新增后台用户
                    sysUser.setLoginName(login.getEmail());
                    sysUser.setCreateBy(login.getEmail());
                    sysUser.setBu(user.getBu());
                    sysUser.setEnginnerId(user.getEnginnerId());
                    sysUser.setTeamleaderId(user.getTeamleaderId());
                    sysUser.setTeamleaderName(user.getTeamleaderName());
                    sysUser.setEnginnerName(user.getName());
                    sysUser.setUserName(user.getName());
                    sysUser.setEmail(user.getEmail());
                    sysUser.setStUserId(user.getId());
                    sysUser.setDelFlag("0");
                    sysUser.setStatus("0");
//                    sysUser.setDeptId(103L);
                    sysUser.setPhonenumber(user.getMobile());
                    // TL
                    String tl = "Team Leader";
                    String fse = "Field Service Engineer";
                    if (tl.equals(user.getPosition())) {
                        Long[] roleIds = new Long[1];
                        roleIds[0] = 4L;
                        sysUser.setRoleIds(roleIds);
                    } else if (fse.equals(user.getPosition())) {
                        Long[] roleIds = new Long[1];
                        roleIds[0] = 3L;
                        sysUser.setRoleIds(roleIds);
                    }
                    sysUserService.insertUser(sysUser);

                }

                /** 查询配置数据（定位上报间隔-location_reporting_interval） */
                Configuration configuration = new Configuration();
                configuration.setName("location_reporting_interval");
                List<Configuration> configurations = configurationService.selectConfigurationList(configuration);
                if (configurations != null && configurations.size() > 0) {
                    double reportingInterval = Double.parseDouble(configurations.get(0).getValue()) * 60 * 1000;
                    user.setLocationReportingInterval(reportingInterval);
                }

                loginLog.setLoginState("1");
                loginLog.setUpdateTime(new Date());
                loginLogMapper.updateLoginLog(loginLog);
                return new ResponseWithData().success(user).msg("登录成功").code(200);
            } else {
                return logOut(login,obj);
            }
        }
        loginLog.setLoginState("2");
        loginLog.setUpdateTime(new Date());
        loginLogMapper.updateLoginLog(loginLog);
        return new ResponseWithData().success().msg("登录失败 调用CC端登录接口返回异常").code(201);
    }

    private ResponseWithData<?> logOut(Login login,JSONObject ccbj) {
        RedisClientUtil.getInstance().initialPool(redisConfig.getIp(), redisConfig.getPort(), redisConfig.getPassword(), redisConfig.getTimeout());
        Jedis redis = RedisClientUtil.getInstance().getJedis();
        if (StringUtils.isNotEmpty(login.getEmail())) {
            User fse = userMapper.selectUserByEmail(login.getEmail());
            if (!ObjectUtils.isEmpty(fse)) {
                if (StringUtils.isNotEmpty(redis.get(fse.getEnginnerId().toString()))) {
                    String token = redis.get(fse.getEnginnerId().toString());
                    redis.del(fse.getEnginnerId().toString());
                    redis.del(token);

                }
            }
        }
        return new

                ResponseWithData().

                success().

                msg(ccbj.get("message").toString()).

                code(203);

    }

    @Override
    public ResponseWithData<?> authorization(String ApiKey) throws Exception {
        String apiKey = global.getApiKey();
        if (!ApiKey.equals(apiKey)) {
            return new ResponseWithData<>().error().msg("ApiKey不正确").code(200);
        }
        RedisClientUtil.getInstance().initialPool(redisConfig.getIp(), redisConfig.getPort(), redisConfig.getPassword(), redisConfig.getTimeout());
        Jedis redis = RedisClientUtil.getInstance().getJedis();
        /** 如果这个key在redis中存在则删除 */
        if (StringUtils.isNotEmpty(redis.get(ApiKey))) {
            String token = redis.get(ApiKey);
            redis.del(ApiKey);
            redis.del(token);
        }
        /** 生成新的ACCESS_TOKEN   token-apikey*/
        String AccessToken = UUID.randomUUID().toString().replaceAll("-", "") + "-" + ApiKey;
        AccessToken = Base64Util.encode(AccessToken);//加密
        /** 正存 */
        redis.set(ApiKey, AccessToken);
        redis.persist(ApiKey);
        /** 反存 */
        redis.set(AccessToken, ApiKey);
        redis.persist(AccessToken);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        jsonObject.put("token", AccessToken);
        jsonObject.put("perpetual", Constants.ACCESS_TOKEN_perpetual);
        jsonObject.put("expire", Constants.ACCESS_TOKEN_TIMES);
        return new ResponseWithData().success(jsonObject).msg("获取授权成功").code(200);
    }

    @Override
    public ResponseWithData<?> authorizationApp(String ApiKey) throws Exception {

        // 验证此用户是否允许登陆
        User user = new User();
        user.setEnginnerId(Long.parseLong(ApiKey));
        List<User> users = userMapper.selectUserList(user);
        if (users != null && users.size() > 0) {
            if ("2".equals(users.get(0).getState())) {
                return new ResponseWithData<>().error().msg("此用户禁止登陆").code(201);
            }
        }
        RedisClientUtil.getInstance().initialPool(redisConfig.getIp(), redisConfig.getPort(), redisConfig.getPassword(), redisConfig.getTimeout());
        Jedis redis = RedisClientUtil.getInstance().getJedis();
        /** 如果这个key在redis中存在则删除 */
        if (StringUtils.isNotEmpty(redis.get(ApiKey))) {
            String token = redis.get(ApiKey);
            redis.del(ApiKey);
            redis.del(token);
        }
        /** 生成新的ACCESS_TOKEN */
        String AccessToken = UUID.randomUUID().toString().replaceAll("-", "") + "-" + ApiKey;
        AccessToken = Base64Util.encode(AccessToken);//加密
        /** 正存 */
        redis.set(ApiKey, AccessToken);
        redis.persist(ApiKey);
        /** 反存 */
        redis.set(AccessToken, ApiKey);
        redis.persist(AccessToken);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        jsonObject.put("token", AccessToken);
        jsonObject.put("perpetual", Constants.ACCESS_TOKEN_perpetual);
        jsonObject.put("expire", Constants.ACCESS_TOKEN_TIMES);
        return new ResponseWithData().success(jsonObject).msg("获取授权成功").code(200);
    }


}
